//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V0.1.2
#include "ws2812b_driver.h"
#include <string.h>


static uint8_t WHT_WS2812B_GRB_BIT_Buffer[WS2812B_COUNT+1][WS2812B_GRB_BIT];


static void IT_Callback(void);
static const WHT_Timer_PWM_Out_Config_t PWM_Out_Config[1] =
{
    {
        .Channel = Timer_CH3,
        .Idle_IT_Callback = IT_Callback,
        .Normal_Polarity = Hig,
        .Normal_Idle_Polarity = Low,
        .Normal_Output_GPIO_Port = PortA,
        .Normal_Output_GPIO_Pin = Pin2,
        .Complementary_Output_State = DISABLE,
        .Brake_Output_State = DISABLE,
    },
};
static WHT_Timer_Config_t PWM_Config =
{
    .Name = Timer2,
    .Cycle_ns = WS2812B_CYCLE_NS,
    .Mode = Timer_Output_Comparison,
    .Config_Count = sizeof(PWM_Out_Config) / sizeof(PWM_Out_Config[0]),
    .Config = &PWM_Out_Config,
};
static void WHT_WS2812B_Driver_Init(void)
{
    WHT_Timer_BSP.WHT_Config(&PWM_Config);
    WHT_Timer_BSP.WHT_Start(&PWM_Config);
}


typedef struct
{
    uint8_t B;//B值
	uint8_t G;//G值
	uint8_t R;//R值
	uint8_t L;//亮度
}WHT_WS2812B_RGB_t;
static volatile FunctionalState Mutex;
static void IT_Callback(void)
{
    Mutex = DISABLE;
}

static void WHT_WS2812B_Reset(void)
{
    vTaskDelay(1);
}
static void WHT_WS2812B_Set_LRGB(uint16_t number, uint32_t lrgb_value)
{
    if (number >= WS2812B_COUNT)
        return;
    
    uint8_t* Send_Buffer = WHT_WS2812B_GRB_BIT_Buffer[number];
    uint32_t LBRG_Value = (((WHT_WS2812B_RGB_t*)&lrgb_value)->L << WS2812B_GRB_BIT) | (((WHT_WS2812B_RGB_t*)&lrgb_value)->B << 16) | (((WHT_WS2812B_RGB_t*)&lrgb_value)->R << 8) | (((WHT_WS2812B_RGB_t*)&lrgb_value)->G << 0);

    /*用户可以在这里添加处理亮度的相关代码*/
    for (char i = 0; i < WS2812B_GRB_BIT; i++)
    {
        Send_Buffer[i] = LBRG_Value & 0x01 ? WS2812B_TIME_1 : WS2812B_TIME_0;
        LBRG_Value >>= 1;
    }
}
static void WHT_WS2812B_Set_All_LRGB(uint32_t lrgb_value)
{
    WHT_WS2812B_Set_LRGB(0, lrgb_value);
    for (uint16_t i = 1; i < WS2812B_COUNT; i++)
    {
        *((uint64_t*)WHT_WS2812B_GRB_BIT_Buffer[i] + 0) = *((uint64_t*)WHT_WS2812B_GRB_BIT_Buffer[0] + 0);
        *((uint64_t*)WHT_WS2812B_GRB_BIT_Buffer[i] + 1) = *((uint64_t*)WHT_WS2812B_GRB_BIT_Buffer[0] + 1);
        *((uint64_t*)WHT_WS2812B_GRB_BIT_Buffer[i] + 2) = *((uint64_t*)WHT_WS2812B_GRB_BIT_Buffer[0] + 2);
    }
}
static void WHT_WS2812B_Start(void)
{
    Mutex = ENABLE;
    WHT_Timer_BSP.WHT_Set_Duty_Cycle_DMA(&PWM_Config, PWM_Out_Config->Channel, WHT_WS2812B_GRB_BIT_Buffer[0], sizeof(WHT_WS2812B_GRB_BIT_Buffer));
    while(Mutex == ENABLE);
    WHT_WS2812B_Reset();
    WHT_Timer_BSP.WHT_Stop(&PWM_Config);
}

static void WHT_WS2812B_Init(void)
{
    WHT_WS2812B_Driver_Init();
    WHT_WS2812B_Set_All_LRGB(0x000000);
}

const WHT_WS2812B_Driver_t WHT_WS2812B_Driver =
{
    .WHT_Init         = WHT_WS2812B_Init,
    .WHT_Start        = WHT_WS2812B_Start,
    .WHT_Set_LRGB     = WHT_WS2812B_Set_LRGB,
    .WHT_Set_All_LRGB = WHT_WS2812B_Set_All_LRGB,
};
